import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
 
/**
 *  @author: hh
 *  @date: 2021/1/12 20:31
 *  @description: 哲学家进餐，模拟哲学家同时拿起左手边筷子
 */
public class PhilosopherMeal extends Thread {
 
    /**
     * 哲学家名称前缀
     */
    private static String NAME_PREFIX = "哲学家";
 
    /**
     * 哲学家编号
     */
    private int philosopherNum;
 
 
    /**
     * 模拟筷子资源信号量
     */
    private volatile List<Semaphore> semaphores;
 
 
    public PhilosopherMeal(int philosopherNum,List<Semaphore> semaphores){
        super(PhilosopherMeal.NAME_PREFIX+String.valueOf(philosopherNum));
        this.philosopherNum = philosopherNum;
        this.semaphores = semaphores;
    }
 
    @Override
    public void run() {
 
        try {
            //哲学家先拿起左手边筷子
            semaphores.get(this.philosopherNum).acquire();
            //哲学家拿起右手边筷子
            semaphores.get(this.getRightSemaphoreIndex(this.philosopherNum)).acquire();
 
            System.out.println(this.getName()+"获取到了筷子"+String.valueOf(this.philosopherNum)+"和"+ String.valueOf(this.getRightSemaphoreIndex(this.philosopherNum)) + "开始吃饭了");
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            semaphores.get(this.philosopherNum).release();
            semaphores.get(this.getRightSemaphoreIndex(this.philosopherNum)).release();
        }
    }
 
    /**
     * 获取当前哲学家右手边的筷子编号
     *
     * @param philosopherNum ：当前哲学家编号
     * @return ：右手边筷子编号
     */
    private int getRightSemaphoreIndex(int philosopherNum){
        return (philosopherNum - 1 < 0) ? semaphores.size() - 1 : philosopherNum - 1;
    }
 
    public static void main(String[] args){
        List<Semaphore> semaphores = new ArrayList<>();
        int counter = 5;
        for(int i = 0 ; i < counter ; i++){
            semaphores.add(new Semaphore(1));
        }
        for(int i = 0 ; i < counter ; i++){
            new PhilosopherMeal(i,semaphores).start();
        }
    }
}